# -*- coding: utf-8 -*-
require 'nkf'
require 'jp_mailer/base64'
require 'jp_mailer/mobile/docomo'
require 'jp_mailer/mobile/au'
require 'jp_mailer/mobile/softbank'

class JpMailer::Base < ActionMailer::Base

  # 本当の送り主（Return-Pathの設定に使う）
  adv_attr_accessor :sender

  private
  def initialize_defaults(*args)
    super
    @charset = 'iso-2022-jp'
  end

  def create!(method_name, *parameters) #:nodoc:
    self.instance_eval %Q{
      class << self
        alias :#{ method_name}_without_mobile_extender :#{ method_name}
        def #{ method_name}_with_mobile_extender(*args)
          #{ method_name}_without_mobile_extender(*args)
          [recipients].flatten.each do |recipient|
            if klass = JpMailer::Mobile::Base.type_of?(recipient)
              self.extend klass
              break
            end
          end
        end
        alias :#{ method_name} :#{ method_name}_with_mobile_extender
      end
    }

    super

    @mail
  end

  def create_mail
    headers['Content-type'] = "text/plain; charset=#{charset}"
    super

    @mail.sender = sender unless sender.nil?

    @mail.extend JpMailer::Base64
    class << @mail
      attr_accessor :jp_mailer
    end
    @mail.jp_mailer = self
    # ヘッダの文字コード指定が未実装なので強引に書き換える
    def @mail.encoded(eol = "\n", charset = "j", dest = nil)
      text = super(eol, "j", dest)
      %w(From To Cc Bcc Subject).each do |key|
        text.gsub!(/^#{key}: .+$/) do |value|
          values = value.gsub!(/^#{key}: /, '').split(/,\s?/)
          encoded_value = values.collect { |v| JpMailer::Base64.header_encode(jp_mailer.charset, jp_mailer.send(:filter, Kconv.kconv(v, Kconv::UTF8, Kconv.guess(v)))) }.join(", ")
          "#{key}: #{encoded_value}"
        end
      end
      text.sub!(/^Subject: .+$/) do |value|
        value.sub!(/^Subject: /, '')
        if jp_mailer.charset == 'iso-2022-jp'
          if jp_mailer.enabled_emotion_conversion? &&
              jp_mailer.respond_to?(:convert_sjis2jis)
            # 絵文字変換が必要であればSJISを経由して変換
            str = NKF.nkf('-Wsx --cp932', value)
            str = Jpmobile::Emoticon::unicodecr_to_external(str,
                                                            jp_mailer.instance_variable_get('@emotion_conversion_table'),
                                                            true)
            str = jp_mailer.convert_sjis2jis(str)
            value = JpMailer::Base64.encode_with_header('iso-2022-jp', str)
          else
            value = NKF.nkf('-jW', value)
          end
        else
          value = JpMailer::Base64.encode_with_header(jp_mailer.charset, jp_mailer.send(:filter, Kconv.kconv(value, Kconv::UTF8, Kconv.guess(value)))) do |ocode, str|
            jp_mailer.convert_emotion(str, ocode == 'shift_jis')
          end
        end
        "Subject: #{value}"
      end
      text
    end

    if charset == 'iso-2022-jp'
      if enabled_emotion_conversion? && respond_to?(:convert_sjis2jis)
        # 絵文字変換が必要であればSJISを経由して変換
        str = NKF.nkf('-Wsx --cp932', @mail.body)
        str = Jpmobile::Emoticon::unicodecr_to_external(str, @emotion_conversion_table, true)
        @mail.body = convert_sjis2jis(str)
      else
        @mail.body = NKF.nkf('-jW', @mail.body)
      end
      @mail.content_transfer_encoding = '7bit'
    else
      @mail.body = JpMailer::Base64.encode(charset, filter(@mail.body)) do |ocode, body|
        # 文字コード変換後、絵文字変換を行い、BASE64形式に変換。
        convert_emotion(body, ocode == 'shift_jis')
      end
      @mail.content_transfer_encoding = 'Base64'
    end

    @mail
  end

  def quote_if_necessary(text, charset)
    text
  end

  public
  def enabled_emotion_conversion?
    false
  end
  private

  def filter(text)
    text
  end

  def perform_delivery_smtp(mail)
    destinations = mail.destinations
    mail.ready_to_send
    sender = mail['return-path'] || mail.sender(nil) || mail.from

    Net::SMTP.start(smtp_settings[:address], smtp_settings[:port], smtp_settings[:domain],
                    smtp_settings[:user_name], smtp_settings[:password], smtp_settings[:authentication]) do |smtp|
      smtp.sendmail(mail.encoded, sender, destinations)
    end
  end

  def perform_delivery_sendmail(mail)
    sendmail_args = sendmail_settings[:arguments]
    sender = mail['return-path'] || mail.sender(nil) || mail.from
    sendmail_args += " -f \"#{sender}\"" if sender
    IO.popen("#{sendmail_settings[:location]} #{sendmail_args}","w+") do |sm|
      sm.print(mail.encoded.gsub(/\r/, ''))
      sm.flush
    end
  end

  public
  def convert_emotion(str, to_sjis = false)
    return str unless enabled_emotion_conversion?
    Jpmobile::Emoticon::unicodecr_to_external(str, @emotion_conversion_table, to_sjis)
  end

end

require 'jp_mailer/ambiguous_parser'
